﻿#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct Student
{
	char* name;		//名字
	int id;
	int name_len;	//名字长度
};
typedef struct Student Stu;

//main169&170&171：结构体及指针读写二进制文本文件和获取字符串有效长度
int main169()
{
	Stu s;	//1.定义结构体变量；
	//2.结构体变量赋值；
	s.id = 1;
	s.name_len = strlen("mike"); //名字长度 4，并不是字符串的实际长度，字符串的结尾为\0，实际长度是5；
	s.name = (char*)malloc(s.name_len + 1);//5
	strcpy(s.name, "mike");//5

	//printf("3.输出结构体变量的值，id：%d   name：%s   name_len：%d\n", s.id, s.name, s.name_len);
	//id：1   name：mike   name_len：4

	FILE* fpWb = fopen("../../../file/FileBinaryConstructWriteRead.txt", "wb");
	if (!fpWb)
	{
		return -1;
	}
	fwrite(&s, sizeof(s), 1, fpWb);
	printf("4.s.name的变量类型char*的初始内存大小为：%d\n", sizeof(s.name));//4	sizeof(s.name) == sizeof(char*)
	//5.结构体s的变量name，是个字符串常量，并不是个字符串数组。所以，上面的写入只写入了个name的地址，
		//没有值“mike”。没有下面这行，那个地址，就是一个野指针；
	fwrite(s.name, s.name_len + 1, 1, fpWb);

	fclose(fpWb);
	free(s.name);

	FILE* fpRb = fopen("../../../file/FileBinaryConstructWriteRead.txt", "rb");
	if (!fpRb)
	{
		return -1;
	}

	fread(&s, sizeof(s), 1, fpRb);

	s.name = (char*)malloc(s.name_len + 1);//5
	fread(s.name, s.name_len + 1, 1, fpRb);

	printf("6.从二进制文本文件中读取到结构体s，此时输出结构体s的信息，int：%d   name：%s   name_len：%d\n", s.id, s.name, s.name_len);
	//int：1   name：mike   name_len：4
	fclose(fpRb);
	free(s.name);

	system("pause");
	return EXIT_SUCCESS;
}
int main170(void)
{
	Stu* s = (Stu*)malloc(sizeof(Stu));
	s->id = 1;
	s->name_len = strlen("mike");//4
	s->name = (char*)malloc(s->name_len + 1);//5
	strcpy(s->name, "mike");//5

	FILE* fpWb = fopen("../../../file/FileBinaryConstructPointerWR.txt", "wb");
	if (!fpWb)
	{
		return -1;
	}

	//fwrite(s, sizeof(s), 1, fpWb);
	fwrite(s, sizeof(Stu), 1, fpWb);
	fwrite(s->name, s->name_len + 1, 1, fpWb);
	fclose(fpWb);

	printf("10.输出结构体s的信息，int：%d   name：%s   name_len：%d\n", s->id, s->name, s->name_len);
	//int：1   name：mike   name_len：4
	free(s->name);
	free(s);

	FILE* fpRb = fopen("../../../file/FileBinaryConstructPointerWR.txt", "rb");
	if (!fpRb)
	{
		return -1;
	}

	//12.这里使用的sizeof(Stu)，得到的是结构体Stu的内存字节数，是固定的。如果用s代替，这就很过分了，
		//因为s只是一个指针地址，是无法求出固定的大小，尤其是还涉及到malloc申请内存，就更不固定了。
	s = (Stu*)malloc(sizeof(Stu));
	fread(s, sizeof(Stu), 1, fpRb);

	//13.一定要先读取结构体s，然后再读取s->name。malloc申请开辟内存，是根据s->name，不先获取s，就没法拿到s->name的地址；
	s->name = (char*)malloc(s->name_len + 1);
	fread(s->name, s->name_len + 1, 1, fpRb);


	printf("11.读取二进制文本后，输出结构体指针s的信息，int：%d   name：%s   name_len：%d\n", s->id, s->name, s->name_len);
	//int：1   name：mike   name_len：4

	fclose(fpRb);

	free(s->name);
	free(s);

	return 0;
}
int main171(void)
{
	char* str = "hello";
	//9.由下面可以知道，sizeof求的变量类型的内存大小，并不是字符串的有效长度，即sizeof(char*)，与指向的内存值没有关系；
		//而strlen求的是字符串常量str的有效长度，并不是实际长度。由于字符串结尾是\0，实际长度是5，而不是4；
	printf("7.用sizeof求出字符串常量str的内存字节数：%d\n", sizeof(str));//4
	printf("8.用strlen求出字符串常量str的长度（内存字节数）：%d\n", strlen(str));//5

	return 0;
}